// Copyright (c) Appeon. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace SnapObjects.Data
{
    internal static class MetaExtensions
    {
        public static IReadOnlyList<Attribute> GetAttributes(this Type type)
        {
            return GetTypeAttributes(type).Select(m => (Attribute)m).ToList();
        }

        private static IReadOnlyList<object> GetTypeAttributes(Type type)
        {
            var attributes = new List<object>();

            if (type.BaseType != null && type.BaseType != typeof(object))
            {
                attributes.AddRange(GetTypeAttributes(type.BaseType));

                AddAttributes(type, attributes);

                return attributes;
            }

            AddAttributes(type, attributes);

            return attributes;
        }

        private static void AddAttributes(Type type, List<object> attributes)
        {
            var customAttributes = type.GetCustomAttributes(false);
            var index = -1;
            object tempAttr = null;

            foreach (var attribute in customAttributes)
            {
                var usageAttribute = attribute.GetType().GetCustomAttribute<AttributeUsageAttribute>();

                if (usageAttribute != null && !usageAttribute.AllowMultiple)
                {
                    tempAttr = attributes.FirstOrDefault(m => m.GetType() == attribute.GetType());

                    if (tempAttr != null)
                    {
                        index = attributes.IndexOf(tempAttr);

                        attributes.RemoveAt(index);

                        attributes.Insert(index, attribute);

                        continue;
                    }
                }

                attributes.Add(attribute);
            }
        }
    }
}
